#include "comm_objbase.h"
#include "cx_DownloadObserver.h"
#include "Cx_timer.h"
#include "cx_string.h"
#include "cx_http.h"
#include "cx_escape_str.h"
#include "cx_memory.h"
#include "cx_debug.h"
#include "cx_file.h"
#include "cx_DownloadLogic.h"
#include "cx_DownloadManager.h"
#include "cx_DownloadOperator.h"

#define FILE_SPACE      L"+"
#define FILE_SPACE      L"+"


/*************************************************************************
* MACRO
*************************************************************************/

//#define __TXT_DEBUG__

/*************************************************************************
* GUID
*************************************************************************/
//unsigned int Previous_pageID = 0;
COMM_DEFINED_GUID( ICxDownloadLogic, 1, "E376239D-A446-4d10-ADCD-BDDFA67C6E0E" )


unsigned long	__Cx_down_Logic_Construct( COMM_REF(ICommO) thiz, void * usr_data );
unsigned long	__Cx_down_Logic_Destruct( COMM_REF(ICommO) thiz );
unsigned long	__Cx_down_Logic_AddRef( COMM_REF(ICommO) thiz );
unsigned long	__Cx_down_Logic_Release( COMM_REF(ICommO) thiz );

static unsigned long	__Cx_down_Logic_NotifyGetLinkEvent( COMM_REF(ICommO) thiz,  IN int status,IN unsigned short* filename );
static unsigned long	__Cx_down_Logic_NotifyEvent( COMM_REF(ICommO) thiz,  IN int status,IN unsigned short* filename );
static unsigned long	__Cx_down_Logic_NotifyStatus( COMM_REF(ICommO) thiz,  IN int status,IN unsigned short* filename );
static unsigned long	__Cx_down_Logic_NotifyProgress(COMM_REF(ICommO) thiz, IN int aReceived,IN unsigned short* filename);
static unsigned long	__Cx_down_Logic_NotifyTotalProgress(COMM_REF(ICommO) thiz, IN int aReceived, IN int aTotalSize,IN unsigned short* filename);


/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __Cx_down_Logic_Construct( COMM_REF(ICommO) thiz, void * usr_data )
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	COMM_UNUSED( usr_data );
	
	if ( NULL == obj_data )
		return COMM_FAILED;

	obj_data->ref_cnt			= 1;

	obj_data->logic_data.downloadid            = 0;
	obj_data->logic_data.url               = NULL;
	obj_data->logic_data.actualurl         = NULL;
	obj_data->logic_data.operatorname          = NULL;
	obj_data->logic_data.resname       = NULL;
	obj_data->logic_data.operatorid            = 0;
	obj_data->logic_data.resid         = 0;
	obj_data->logic_data.maxresid        = 0;
	obj_data->pBookDownloadManager         = comm_cx_create_download_manager(NULL);           
	obj_data->downloadOperator             = NULL;
	//obj_data->iLib                         = NULL;
	obj_data->currentresid             = 0;
	obj_data->observer                     = NULL;
	obj_data->isDownload                   = QTRUE;
	//obj_data->filename                     = NULL;
	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __Cx_down_Logic_Destruct( COMM_REF(ICommO) thiz )
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;
	
	COMMO_SAFE_RELEASE( obj_data->observer );
	COMMO_SAFE_RELEASE( obj_data->pBookDownloadManager );
	COMMO_SAFE_RELEASE( obj_data->downloadOperator );
	//cx_free(obj_data->filename);
	//obj_data->filename = NULL;
	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __Cx_down_Logic_AddRef( COMM_REF(ICommO) thiz )
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;
	
	obj_data->ref_cnt++;
	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __Cx_down_Logic_Release( COMM_REF(ICommO) thiz )
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;
	
	obj_data->ref_cnt -= 1;

	if ( 0 == obj_data->ref_cnt )
	{
		comm_obj_delete( (void *)thiz );
	}
	
	return COMM_OK;
}

unsigned long __Cx_down_Logic_SetObserver( COMM_REF(ICommO) thiz, COMM_REF(ICommO) obsvr )
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	COMMO_ASSIGN( obj_data->observer, obsvr );

	if(obj_data->pBookDownloadManager)
	{
		//download_manager_ptr_t d_obj_data = (download_manager_ptr_t)COMM_GET_DATA( obj_data->pBookDownloadManager );
		//if(d_obj_data)
			IDownloadManager_SetObserver(obj_data->pBookDownloadManager,obsvr);
	}

	return COMM_OK;
}

unsigned long	__Cx_down_Logic_Operate( COMM_REF(ICommO) thiz, IN unsigned short* filename)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	if(obj_data->pBookDownloadManager == NULL)
		return COMM_FAILED;

	return IDownloadManager_Operate( obj_data->pBookDownloadManager, filename);
}

static unsigned long	__Cx_down_Logic_Delete( COMM_REF(ICommO) thiz, IN unsigned short* filename,IN QBOOL deletefile)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	if(obj_data->pBookDownloadManager == NULL)
		return COMM_FAILED;

	return IDownloadManager_DelTaskOne( obj_data->pBookDownloadManager, filename,deletefile);
}

unsigned long	__Cx_down_Logic_DeleteAll( COMM_REF(ICommO) thiz)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	if(obj_data->pBookDownloadManager == NULL)
		return COMM_FAILED;

	return IDownloadManager_DeleteAll( obj_data->pBookDownloadManager);
}

unsigned long	__Cx_down_Logic_StartAll( COMM_REF(ICommO) thiz)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	if(obj_data->pBookDownloadManager == NULL)
		return COMM_FAILED;

	return IDownloadManager_StartAll( obj_data->pBookDownloadManager);
}

unsigned long	__Cx_down_Logic_PauseAll( COMM_REF(ICommO) thiz)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	if(obj_data->pBookDownloadManager == NULL)
		return COMM_FAILED;

	return IDownloadManager_PauseAll( obj_data->pBookDownloadManager);
}

unsigned long	__Cx_down_Logic_LaunchTask( COMM_REF(ICommO) thiz, IN QBOOL islaunchtask)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	if(obj_data->pBookDownloadManager == NULL)
		return COMM_FAILED;

	return IDownloadManager_LaunchTask( obj_data->pBookDownloadManager,islaunchtask);
}

unsigned long	__Cx_down_Logic_Save( COMM_REF(ICommO) thiz)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	if(obj_data->pBookDownloadManager == NULL)
		return COMM_FAILED;

	return IDownloadManager_Save( obj_data->pBookDownloadManager);
};

static unsigned long	__Cx_down_Logic_NotifyGetLinkEvent( COMM_REF(ICommO) thiz,  IN int status,IN unsigned short* filename )
{
	download_operator_data_ptr_t o_obj_data;
	get_link_event_data_t get_link_event_data;
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );
	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL == obj_data->downloadOperator )
		return COMM_FAILED;

	o_obj_data = (download_operator_data_ptr_t)COMM_GET_DATA( obj_data->downloadOperator );
	if ( NULL == o_obj_data )
		return COMM_FAILED;

	get_link_event_data.filename = o_obj_data->filename;
	get_link_event_data.resid = o_obj_data->resid;
	get_link_event_data.event = status;
	get_link_event_data.data = NULL;
	get_link_event_data.eventtype = EQOnlineEventType;
	return IComm_cx_DownLoadObserver_SendDownloadNotify( obj_data->observer, EQGetLinkEventType, (void*)(&get_link_event_data ));
}

static unsigned long	__Cx_down_Logic_NotifyEvent( COMM_REF(ICommO) thiz,  IN int status,IN unsigned short* filename )
{
	download_operator_data_ptr_t o_obj_data;
	event_data_t event_data;
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );
	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL == obj_data->downloadOperator )
		return COMM_FAILED;

	o_obj_data = (download_operator_data_ptr_t)COMM_GET_DATA( obj_data->downloadOperator );
	if ( NULL == o_obj_data )
		return COMM_FAILED;

	
	event_data.filename = o_obj_data->filename;
	event_data.event = status;
	event_data.data = NULL;
	event_data.eventtype = EQOnlineEventType;
	IComm_cx_DownLoadObserver_SendDownloadNotify( obj_data->observer, EQEventType, (void*)(&event_data ));
	return COMM_OK;
}

static unsigned long	__Cx_down_Logic_NotifyStatus ( COMM_REF(ICommO) thiz,  IN int status,IN unsigned short* filename )
{
	download_operator_data_ptr_t o_obj_data;
	status_type_data_t status_t;
	int len;
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );
	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL == obj_data->downloadOperator )
		return COMM_FAILED;

	o_obj_data = (download_operator_data_ptr_t)COMM_GET_DATA( obj_data->downloadOperator );
	if ( NULL == o_obj_data )
		return COMM_FAILED;

	o_obj_data->downstatus = status;
	len = cx_strlen_w((CONST QWCHAR*)o_obj_data->filename);
	status_t.filename = (unsigned short *)cx_malloc((len + 1)*sizeof(unsigned short));
	cx_strcpy_w((QWCHAR*)status_t.filename,(CONST QWCHAR*)o_obj_data->filename);
	
	if(o_obj_data->resname)
	{
		int len = cx_strlen_w((CONST QWCHAR*)o_obj_data->resname);
		status_t.operatorname = (unsigned short *)cx_malloc((len + 1)*sizeof(unsigned short));
		cx_strcpy_w((QWCHAR*)status_t.operatorname,(CONST QWCHAR*)o_obj_data->resname);
	}
	else
		status_t.operatorname = NULL;
	status_t.status = status;
	status_t.data = NULL;
	status_t.eventtype = EQOnlineEventType;
	
		if(download_task_finish == status)
		{
			message_data_t message_data;
			message_data.wParam = (unsigned int)(o_obj_data);
			message_data.lParam = 0;
			message_data.fromModuleid = -1;
			IComm_cx_DownLoadObserver_SendStoreNotify( obj_data->observer, Online_Add, (void*)(&message_data ));
			
		}		
	
	IComm_cx_DownLoadObserver_SendDownloadNotify( obj_data->observer, EQStatusType, (void*)(&status_t));

	if(download_task_error == status)
		o_obj_data->resid = obj_data->currentresid;
	else if(download_task_finish == status)
		obj_data->currentresid = o_obj_data->resid;


	return COMM_OK;
FAILED:
	return COMM_FAILED;
}

static unsigned long	__Cx_down_Logic_NotifyProgress(COMM_REF(ICommO) thiz, IN int aReceived,IN unsigned short* filename)
{
	download_operator_data_ptr_t o_obj_data;
	progress_data_t progress_data;
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );
	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL == obj_data->downloadOperator )
		return COMM_FAILED;

	o_obj_data = (download_operator_data_ptr_t)COMM_GET_DATA( obj_data->downloadOperator );
	if ( NULL == o_obj_data )
		return COMM_FAILED;

	progress_data.filename = o_obj_data->filename;
	progress_data.received = aReceived;
	progress_data.totalSize = 0;
	progress_data.per = 0.0;
	progress_data.maxchatper = o_obj_data->maxresid;
	progress_data.eventtype = EQOnlineEventType;
	return IComm_cx_DownLoadObserver_SendDownloadNotify( obj_data->observer, EQProgressType, (void*)(&progress_data ));
}

static unsigned long	__Cx_down_Logic_NotifyTotalProgress(COMM_REF(ICommO) thiz, IN int aReceived, IN int aTotalSize,IN unsigned short* filename)
{
	progress_data_t progress_data;
	download_operator_data_ptr_t o_obj_data;
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );
	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL == obj_data->downloadOperator )
		return COMM_FAILED;

	o_obj_data = (download_operator_data_ptr_t)COMM_GET_DATA( obj_data->downloadOperator );
	if ( NULL == o_obj_data )
		return COMM_FAILED;

	progress_data.filename = o_obj_data->filename;
//	if(o_obj_data->downloadid == PAGE_DOWNLOAD_BOOK)
//	{
//		progress_data.per = (float)o_obj_data->resid*100/o_obj_data->maxresid + (float)aReceived*100 /(aTotalSize*o_obj_data->maxresid);
//	}
//	else
	{
		progress_data.received = o_obj_data->receivenumber;
		progress_data.totalSize = aTotalSize;
		progress_data.per = (float)o_obj_data->receivenumber*100 / aTotalSize;
	}

	progress_data.maxchatper = o_obj_data->maxresid;
	progress_data.eventtype = EQOnlineEventType;
	return IComm_cx_DownLoadObserver_SendDownloadNotify( obj_data->observer, EQProgressType, (void*)(&progress_data ));
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
COMM_EXPORT COMM_REF(ICommO) comm_cx_create_download_logic( void * reserved )
{
	//static const 
	comm_coclass_desc_t __coclass_desc;	
		void * __coclass_vtbl[21];// =
int i=0;//	{
		// ICommO
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_Construct;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_Destruct;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_AddRef;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_Release;
 
		// IDownloadStatusObserver
__coclass_vtbl[i++] = 			(void *)__Cx_down_Logic_NotifyGetLinkEvent;
__coclass_vtbl[i++] = 			(void *)__Cx_down_Logic_NotifyEvent;
__coclass_vtbl[i++] = 			(void *)__Cx_down_Logic_NotifyStatus;
__coclass_vtbl[i++] =			(void *)__Cx_down_Logic_NotifyProgress;
__coclass_vtbl[i++] =			(void *)__Cx_down_Logic_NotifyTotalProgress;
		// IDownloadLogic
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_SetObserver;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_Operate;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_Delete;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_DeleteAll;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_StartAll;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_PauseAll;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_LaunchTask;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_Save;

__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_AddDownloadRequest;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_SetDownloadPath;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_SetIap;
__coclass_vtbl[i++] = 	(void *)__Cx_down_Logic_GetDownloadInfoList;
	//};
			
		__coclass_desc.vtbl_size	= (unsigned long)sizeof(__coclass_vtbl);
		__coclass_desc.vtbl_funcs	= (unsigned char *)__coclass_vtbl;
		__coclass_desc.priv_size	= (unsigned long)sizeof(__struct_comm_download_logic_data);
		


	return ( COMM_REF(ICommO) )comm_obj_new( (comm_coclass_desc_ptr_t)&__coclass_desc, reserved );
}



unsigned long __Cx_down_Logic_AddDownloadRequest( COMM_REF(ICommO) thiz, char* filename,char* url)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );
	unsigned short* buff_ptr = NULL;
	int size;
	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL == filename )
		return COMM_FAILED;
	if ( NULL == url )
		return COMM_FAILED;

	obj_data->logic_data.downloadid = PAGE_DOWNLOAD_WHOLE;


	if(obj_data->pBookDownloadManager == NULL)
		return COMM_FAILED;

	
	
	//const char* url = (const char*)aUrl;
	size = (cx_strlen_a(url)+1)*UTF8_ENCODING_LENGTH;
	buff_ptr = (unsigned short*)cx_malloc(size);
	if(buff_ptr)
	{
		cx_memset(buff_ptr,0,size);
		cx_utf8_to_ucs2_string( (void*)buff_ptr, size, (void*)url, cx_strlen_a(url) );
		copy_string_w(&(obj_data->logic_data.url),buff_ptr);
		copy_string_w(&(obj_data->logic_data.actualurl),buff_ptr);		
		cx_free(buff_ptr);
	}
	
	size = (cx_strlen_a(filename)+1)*UTF8_ENCODING_LENGTH;
	buff_ptr = (unsigned short*)cx_malloc(size);
	if(buff_ptr)
	{
		cx_memset(buff_ptr,0,size);
		cx_utf8_to_ucs2_string( (void*)buff_ptr, size, (void*)filename, cx_strlen_a(filename) );
		copy_string_w(&(obj_data->logic_data.operatorname),buff_ptr);
		copy_string_w(&(obj_data->logic_data.operatorid),buff_ptr);
		cx_free(buff_ptr);
	}		
	
	IDownloadManager_AddTask( obj_data->pBookDownloadManager, &(obj_data->logic_data) );
	obj_data->logic_data.downloadid            = 0;
	obj_data->logic_data.url               = NULL;
	obj_data->logic_data.actualurl         = NULL;
	obj_data->logic_data.operatorname          = NULL;
	obj_data->logic_data.resname       = NULL;
	obj_data->logic_data.operatorid            = 0;
	obj_data->logic_data.resid         = 0;
	obj_data->logic_data.maxresid        = 0;

	
	return COMM_OK;
}


unsigned long __Cx_down_Logic_SetDownloadPath( COMM_REF(ICommO) thiz, unsigned short* path)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );
	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL == path )
		return COMM_FAILED;
	IDownloadManager_SetDownloadPath( obj_data->pBookDownloadManager, path);
}

unsigned long __Cx_down_Logic_SetIap( COMM_REF(ICommO) thiz, int iap)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );
	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL == iap )
		return COMM_FAILED;
	IDownloadManager_SetIap( obj_data->pBookDownloadManager, iap);
}


unsigned long __Cx_down_Logic_GetDownloadInfoList( COMM_REF(ICommO) thiz, void* data)
{
	comm_download_logic_data_ptr_t obj_data = (comm_download_logic_data_ptr_t)COMM_GET_DATA( thiz );
	if ( NULL == obj_data )
		return COMM_FAILED;
//	if ( NULL == data )
//		return COMM_FAILED;
	IDownloadManager_GetDownloadInfoList( obj_data->pBookDownloadManager, data);
}


//#if defined(__cplusplus)
//}
//#endif	// #if defined(__cplusplus)
